home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mush-7.1.1 / setopts.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-02  |  20.3 KB  |  780 lines

  1. /* setopts.c    (c) copyright 1986 (Dan Heller) */
  2.  
  3. #include "mush.h"
  4. #include "bindings.h"
  5.  
  6. static void
  7. insert_option(list, opt, order)
  8. struct options **list, *opt;
  9. int order;    /* Insert in sorted order? */
  10. {
  11.     while (*list && (!order || (strcmp((*list)->option, opt->option) < 1)))
  12.     list = &((*list)->next);
  13.     opt->next = *list;
  14.     *list = opt;
  15. }
  16.  
  17. /* add an option indicated by "set option[=value]" or by "alias name alias"
  18.  * function is recursive, so multilists get appended accordingly
  19.  */
  20. add_option(list, argv)
  21. register struct options **list;
  22. register char **argv;
  23. {
  24.     register struct options *tmp;
  25.     register char *option, *value = NULL;
  26.  
  27.     if (!(option = *argv))
  28.     return 1;
  29.     /* check for one of three forms:
  30.      * option=value  option= value  option = value
  31.      */
  32.     if (value = index(option, '=')) {
  33.     if (value == option) {
  34.         print("No variable specified\n");
  35.         return 0;
  36.     }
  37.     /* "option=value" strip into option="option" value="value" */
  38.     *value++ = 0; /* option is now a null terminated `option' */
  39.     if (*value || (value = *++argv)) { /* "option= value" */
  40.         ++argv;
  41.     }
  42.     } else if (*++argv && !strcmp(*argv, "=")) {
  43.     if (value = *++argv) /* "option = value" */
  44.         ++argv;
  45.     }
  46.  
  47.     /* check for internal vars that can't be set this way */
  48.     if (*list == set_options && check_internal(option)) {
  49.     print("You can't change %s with \"set\".\n", option);
  50.     return 0;
  51.     }
  52.  
  53.     /* check to see if option is already set by attempting to unset it */
  54.     if (un_set(list, option) == -1)
  55.     return 0;
  56.  
  57.     /* now make a new option struct and set fields */
  58.     if (!(tmp = (struct options *)calloc((unsigned)1,sizeof(struct options)))) {
  59.     error("calloc");
  60.     return -1;
  61.     }
  62.     tmp->option = savestr(option);
  63.     tmp->value = savestr(value); /* strdup handles the NULL case */
  64.  
  65.     insert_option(list, tmp, (list != &own_hdrs));
  66.  
  67.     /* check for options which must have values or are used frequently */
  68.     if (*list == set_options) {
  69. #if defined(CURSES) || defined(SUNTOOL)
  70.     if (!strcmp(tmp->option, "no_reverse"))
  71.         turnoff(glob_flags, REV_VIDEO);
  72.     else
  73. #endif /* CURSES || SUNTOOL */
  74. #ifdef SUNTOOL
  75.     if (!strcmp(tmp->option, "tool_help"))
  76.         if (tmp->value && *(tmp->value))
  77.         strdup(tool_help, tmp->value);
  78.         else {
  79.         int n = 0;
  80.         char *p = getpath(TOOL_HELP, &n);
  81.         if (n)
  82.             strdup(tool_help, "tool_help");
  83.         else
  84.             strdup(tool_help, p);
  85.         strdup(tmp->value, tool_help);
  86.         }
  87.     else
  88. #endif /* SUNTOOL */
  89.     if (!strcmp(tmp->option, "cmd_help"))
  90.         if (tmp->value && *(tmp->value))
  91.         strdup(cmd_help, tmp->value);
  92.         else {
  93.         int n = 0; /* don't ignore no such file or directory */
  94.         char *p = getpath(COMMAND_HELP, &n);
  95.         if (n)
  96.             strdup(cmd_help, "cmd_help");
  97.         else
  98.             strdup(cmd_help, p);
  99.         strdup(tmp->value, cmd_help);
  100.         }
  101.     else if (!strcmp(tmp->option, "prompt"))
  102.         prompt = (tmp->value)? tmp->value : DEF_PROMPT;
  103.     else if (!strcmp(tmp->option, "warning"))
  104.         turnon(glob_flags, WARNING);
  105.     else if (!strcmp(tmp->option, "mil_time"))
  106.         turnon(glob_flags, MIL_TIME);
  107. #ifndef MSG_SEPARATOR
  108.     else if (!strcmp(tmp->option, "date_received"))
  109.         turnon(glob_flags, DATE_RECV);
  110. #endif /* MSG_SEPARATOR */
  111.     else if (!strcmp(tmp->option, "escape"))
  112.         escape = (tmp->value)? tmp->value : DEF_ESCAPE;
  113.     else if (!strcmp(tmp->option, "hdr_format"))
  114.         hdr_format = (tmp->value)? tmp->value : DEF_HDR_FMT;
  115.     else if (!strcmp(tmp->option, "crt")) {
  116.         if (!istool)
  117.         crt = (tmp->value)? max(atoi(tmp->value), 2): 18;
  118.     }
  119.     else if (!strcmp(tmp->option, "screen")) {
  120.         screen = (tmp->value)? max(atoi(tmp->value), 1): 18;
  121. #ifdef CURSES
  122.         if (iscurses && screen > LINES-2)
  123.         screen = LINES-2;
  124. #endif /* CURSES */
  125.     } else if (!strcmp(tmp->option, "wrapcolumn")) {
  126.         char wval[16];
  127.         wrapcolumn =
  128.         (tmp->value && *(tmp->value))? max(atoi(tmp->value), 0): 78;
  129. #ifdef CURSES
  130.         /* Use COLS-2 because of silly terminals like vt100 */
  131.         if (iscurses && wrapcolumn > COLS - 2)
  132.         wrapcolumn = COLS - 2;
  133. #endif /* CURSES */
  134.         xfree(tmp->value);
  135.         tmp->value = savestr(sprintf(wval, "%d", wrapcolumn));
  136.     } else if (!strcmp(tmp->option, "history"))
  137.         init_history((value && *value)? atoi(value) : 1);
  138.     else if (!strcmp(tmp->option, "realname")) {
  139.         char *new[4];
  140.         new[1] = "NAME";
  141.         new[2] = tmp->value;
  142.         new[3] = NULL;
  143.         (void) Setenv(3, new); /* new[0] is ignored */
  144.     } else if (!strcmp(tmp->option, "known_hosts")) {
  145.         register char *p;
  146.         int n;
  147.         /* in case user separated with commas */
  148.         for (p = index(tmp->value, ','); p; p = index(p+1, ','))
  149.         *p = ' ';
  150.         free_vec(known_hosts);
  151.         known_hosts = mk_argv(tmp->value, &n, FALSE);
  152.     } else if (!strcmp(tmp->option, "hostname")) {
  153.         register char *p;
  154.         int n;
  155.         /* in case user separated with commas */
  156.         for (p = index(tmp->value, ','); p; p = index(p+1, ','))
  157.         *p = ' ';
  158.         free_vec(ourname);
  159.         ourname = mk_argv(tmp->value, &n, FALSE);
  160.     } else if (!strcmp(tmp->option, "complete")) {
  161.         if (value && *value) {
  162.         m_xlate(value); /* use the original, don't change tmp->value */
  163.         complete = value[0];
  164.         complist = value[1];
  165.         } else {
  166.         tmp->value = savestr("\\E\\CD");
  167.         complete = '\033';
  168.         complist = '\004';
  169.         }
  170.     }
  171.     }
  172.  
  173.     if (*argv)
  174.     return add_option(list, argv);
  175.     return 1;
  176. }
  177.  
  178. /*
  179.  * If str is NULL, just print options and their values. Note that numerical
  180.  * values are not converted to int upon return.  If str is not NULL
  181.  * return the string that matched, else return NULL;
  182.  */
  183. char *
  184. do_set(list, str)
  185. register struct options *list;
  186. register char *str;
  187. {
  188.     register struct options *opts;
  189.  
  190.     if (!str)
  191.     (void) do_pager(NULL, TRUE); /* page using internal pager */
  192.  
  193.     for (opts = list; opts; opts = opts->next)
  194.     if (!str) {
  195.         (void) do_pager(opts->option, FALSE);
  196.         if (opts->value && *opts->value) {
  197.         (void) do_pager("     \t", FALSE);
  198.         (void) do_pager(opts->value, FALSE);
  199.         }
  200.         if (do_pager("\n", FALSE) == EOF)
  201.         break;
  202.     } else {
  203.         if (strcmp(str, opts->option))
  204.         continue;
  205.         if (opts->value)
  206.         return opts->value;
  207.         else
  208.         return "";
  209.     }
  210.  
  211.     if (!str)
  212.     (void) do_pager(NULL, FALSE); /* terminate internal pager */
  213.  
  214.     /* if we still haven't matched, check for environment vars */
  215.     if (str && list == set_options) {
  216.     register int N, n;
  217.     for (N = 0; environ[N]; N++) {
  218.         char *p = index(environ[N], '=');
  219.         if (p)
  220.         *p = 0;
  221.         n = lcase_strncmp(str, environ[N], -1);
  222.         if (p)
  223.         *p = '=';
  224.         if (!n)
  225.         return p+1;
  226.     }
  227.     }
  228.     return NULL;
  229. }
  230.  
  231. /*
  232.  * unset the variable described by p in the list "list".
  233.  * if the variable isn't set, then return 0, else return 1.
  234.  */
  235. un_set(list, p)
  236. register struct options **list;
  237. register char *p;
  238. {
  239.     register struct options *opts = *list, *tmp;
  240.  
  241.     if (!list || !*list || !p || !*p)
  242.     return 0;
  243.     if (*list == set_options) {
  244. #if defined(CURSES) || defined(SUNTOOL)
  245.     if (!strcmp(p, "no_reverse"))
  246.         turnon(glob_flags, REV_VIDEO);
  247.     else
  248. #endif /* CURSES || SUNTOOL */
  249.     if (!strcmp(p, "prompt"))
  250.         prompt = DEF_PROMPT;
  251.     else if (!strcmp(p, "warning"))
  252.         turnoff(glob_flags, WARNING);
  253.     else if (!strcmp(p, "mil_time"))
  254.         turnoff(glob_flags, MIL_TIME);
  255. #ifndef MSG_SEPARATOR
  256.     else if (!strcmp(p, "date_received"))
  257.         turnoff(glob_flags, DATE_RECV);
  258. #endif /* MSG_SEPARATOR */
  259.     else if (!strcmp(p, "escape"))
  260.         escape = DEF_ESCAPE;
  261.     else if (!strcmp(p, "hdr_format"))
  262.         hdr_format = DEF_HDR_FMT;
  263.     else if (!strcmp(p, "crt"))
  264.         crt = 18;
  265.     else if (!strcmp(p, "screen")) {
  266.         screen = 18;
  267. #ifdef CURSES
  268.         if (iscurses && screen > LINES-2)
  269.         screen = LINES-2;
  270. #endif /* CURSES */
  271.     } else
  272. #ifdef SUNTOOL
  273.     if (!strcmp(p, "tool_help")) {
  274.         int n = 0;
  275.         char *p2 = getpath(TOOL_HELP, &n);
  276.         if (n)
  277.         strdup(tool_help, "tool_help");
  278.         else
  279.         strdup(tool_help, p2);
  280.     } else
  281. #endif /* SUNTOOL */
  282.     if (!strcmp(p, "cmd_help")) {
  283.         int n = 0; /* don't ignore no such file or directory */
  284.         char *p2 = getpath(COMMAND_HELP, &n);
  285.         if (n)
  286.         strdup(cmd_help, "cmd_help");
  287.         else
  288.         strdup(cmd_help, p2);
  289.     } else if (!strcmp(p, "wrapcolumn"))
  290.         wrapcolumn = 0;
  291.     else if (!strcmp(p, "history"))
  292.         init_history(1);
  293.     else if (!strcmp(p, "known_hosts")) {
  294.         free_vec(known_hosts);
  295.         known_hosts = DUBL_NULL;
  296.     } else if (!strcmp(p, "hostname")) {
  297.         free_vec(ourname);
  298.         ourname = DUBL_NULL;
  299.     } else if (ison(glob_flags, IS_GETTING) && !strcmp(p, "edit_hdrs")) {
  300.         wprint("You mush finish this letter first.\n");
  301.         return -1;
  302.     } else if (!strcmp(p, "complete"))
  303.         complete = complist = 0;
  304.     }
  305.  
  306.     if (!strcmp(p, opts->option)) {
  307.     *list = (*list)->next;
  308.     xfree (opts->option);
  309.     if (opts->value)
  310.         xfree(opts->value);
  311.     xfree((char *)opts);
  312.     return 1;
  313.     }
  314.     for ( ; opts->next; opts = opts->next)
  315.     if (!strcmp(p, opts->next->option)) {
  316.         tmp = opts->next;
  317.         opts->next = opts->next->next;
  318.         xfree (tmp->option);
  319.         if (tmp->value)
  320.         xfree(tmp->value);
  321.         xfree ((char *)tmp);
  322.         return 1;
  323.     }
  324.     return 0;
  325. }
  326.  
  327. /* The functions below return 0 since they don't affect
  328.  * messages.
  329.  */
  330. set(n, argv, list)
  331. register int n;
  332. register char **argv;
  333. char *list;
  334. {
  335.     void list_to_str();
  336.     char firstchar = **argv;
  337.     register char *cmd = *argv;
  338.     register struct options **optlist;
  339.     char buf[BUFSIZ];
  340.  
  341.     if (*cmd == 'u')
  342.     cmd += 2;
  343.     if (*++argv && !strcmp(*argv, "-?"))
  344.     return help(0, (*cmd == 'i')? "ignore": "set", cmd_help);
  345.  
  346.     if (*argv && **argv == '?') {
  347.     int incurses;
  348.     if (!strcmp(*argv, "?all")) {
  349.         if (incurses = iscurses) /* assign and compare to TRUE */
  350.         clr_bot_line(), iscurses = FALSE;
  351.         (void) do_pager(NULL, TRUE); /* start internal pager */
  352.         for (n = 0; variable_stuff(n, NULL, buf); n++)
  353.         if (do_pager(strcat(buf, "\n"), FALSE) == EOF)
  354.             break;
  355.         (void) do_pager(NULL, FALSE); /* terminate pager */
  356.         iscurses = incurses;
  357.     } else {
  358.         /* May return null if variable not set. */
  359.         (void) variable_stuff(0, (*argv)+1, buf);
  360.         print("%s\n", buf);
  361.     }
  362.     return 0;
  363.     }
  364.  
  365.     if (firstchar == 'u') {
  366.     if (!*argv) {
  367.         print("%s what?\n", cmd);
  368.         return -1;
  369.     } else {
  370.         optlist = (*cmd == 'i')? &ignore_hdr : &set_options;
  371.         do  if (!strcmp(*argv, "*")) {
  372.             while (*optlist)
  373.             (void) un_set(optlist, (*optlist)->option);
  374. #ifdef SUNTOOL
  375.             if (*cmd != 'i')
  376.             opts_panel_item(NULL);
  377. #endif /* SUNTOOL */
  378.         } else if (!un_set(optlist, *argv) &&
  379.             do_set(set_options, "warning"))
  380.             print("un%s: %s not set\n",
  381.             (*cmd == 'i')? "ignore" : "set", *argv);
  382. #ifdef SUNTOOL
  383.         else if (*cmd != 'i')
  384.             opts_panel_item(*argv);
  385. #endif /* SUNTOOL */
  386.         while (*++argv);
  387. #ifdef SUNTOOL
  388.         if (*cmd == 'i' && istool > 1)
  389.         update_list_textsw(&ignore_hdr);
  390. #endif /* SUNTOOL */
  391.     }
  392.     return 0;
  393.     }
  394.  
  395.     if (!*argv) {
  396.     (void) do_set((*cmd == 'i')? ignore_hdr: set_options, NULL);
  397.     return 0;
  398.     }
  399.  
  400.     /*
  401.      * Check for input redirection.  If so, set the variable to the ascii
  402.      * value of the current msg_list.
  403.      */
  404.     if (ison(glob_flags, IS_PIPE)) {
  405.     char *newargv[4];
  406.  
  407.     if (*cmd == 'i') {
  408.         print("You can't pipe to the \"%s\" command.\n", cmd);
  409.         return -1;
  410.     }
  411.     if (newargv[0] = index(argv[0], '='))
  412.         *newargv[0] = 0;
  413.     list_to_str(list, buf);
  414.     if (!buf[0] && !do_set(set_options, argv[0])) {
  415.         return 0;
  416.     }
  417.     newargv[0] = argv[0];
  418.     newargv[1] = "=";
  419.     newargv[2] = buf;
  420.     newargv[3] = NULL;
  421.     (void) add_option(&set_options, newargv);
  422.     return 0;
  423.     }
  424.  
  425.     /*
  426.      * finally, just set the variable the user requested.
  427.      */
  428.     (void) add_option((*cmd == 'i')? &ignore_hdr: &set_options, argv);
  429. #ifdef SUNTOOL
  430.     if (istool > 1)
  431.     if (*cmd == 'i')
  432.         update_list_textsw(&ignore_hdr);
  433.     else
  434.         opts_panel_item(argv[0]);
  435. #endif /* SUNTOOL */
  436.     return 0;
  437. }
  438.  
  439. /*
  440.  *   The alts list is a list of hostnames or pathnames where the user
  441.  * has an account.  If he doesn't specify "metoo", then when replying
  442.  * to mail, if his address is listed, it will be removed.  The syntax
  443.  * is compatible with ucb Mail in that just hostnames can be used.
  444.  * However, there is an added feature that mush provides which another
  445.  * login name or path to another login can be specified by preceding the
  446.  * path or login with a !
  447.  * "argv" may be a file pointer to write the data into by use of save_opts()
  448.  */
  449. alts(argc, argv)
  450. register char **argv;
  451. {
  452.     char buf[BUFSIZ], *p;
  453.  
  454.     /* check here first because a 0 argc means to write it to a file */
  455.     if (argc <= 1) {
  456.     int n;
  457.     if (!alternates)
  458.         return 0;
  459.     if (argc == 0)
  460.         (void) fprintf((FILE *)argv, "alts ");
  461.     for (n = 0; alternates[n]; n++) {
  462.         p = 0;
  463.         buf[0] = 0;
  464.         (void) strcpy(&buf[1], alternates[n]);
  465.         if (buf[1] != '*')
  466.         (void) reverse(&buf[1]);
  467.         if ((p = rindex(&buf[1], '!')) && !lcase_strncmp(p+1, login, -1))
  468.         *p = 0;
  469.         else if (buf[1] != '*')
  470.         buf[0] = '!';
  471.         if (argc == 0)
  472.         (void) fprintf((FILE *)argv, "%s ", *buf? buf : &buf[1]);
  473.         else
  474.         wprint("%s ", *buf? buf : &buf[1]);
  475.         if (p)
  476.         *p = '!';
  477.     }
  478.     if (argc == 0)
  479.         (void) fputc('\n', (FILE *)argv);
  480.     else
  481.         wprint("\n");
  482.     return 0;
  483.     }
  484.  
  485.     if (argc-- && *++argv && !strcmp(*argv, "-?"))
  486.     return help(0, "alts", cmd_help);
  487.  
  488.     free_vec(alternates);
  489.     if (alternates = (char **)calloc((unsigned)argc+1, sizeof(char *)))
  490.     while (argc-- > 0) {
  491.         if (argv[argc][0] == '!')
  492.         alternates[argc] = savestr(reverse(&argv[argc][1]));
  493.         else if (argv[argc][0] == '*') {
  494.         alternates[argc] = savestr(argv[argc]);
  495.         } else {
  496.         p = buf + Strcpy(buf, argv[argc]);
  497.         *p++ = '!', p += Strcpy(p, login);
  498.         alternates[argc] = savestr(reverse(buf));
  499.         }
  500.     }
  501.     return 0;
  502. }
  503.  
  504. save_opts(cnt, argv)
  505. char **argv;
  506. {
  507.     char file[MAXPATHLEN], *tmp;
  508.     register FILE *fp;
  509.  
  510.     if (cnt && *++argv && !strcmp(*argv, "-?"))
  511.     return help(0, "source", cmd_help);
  512.     if (cnt && *argv)
  513.     (void) strcpy(file, *argv);
  514.     else if ((tmp = getenv("MUSHRC")) || (tmp = getenv("MAILRC")))
  515.     (void) strcpy(file, tmp);
  516.     else {
  517.     char *home = do_set(set_options, "home");
  518.     if (!home || !*home)
  519.         home = ALTERNATE_HOME;
  520.     /* if .mushrc doesn't exist, check .mailrc. If neither, force .mushrc */
  521.     if (Access(sprintf(file, "%s/%s", home, MAILRC), F_OK) &&
  522.         Access(sprintf(file, "%s/%s", home, ALTERNATE_RC), F_OK))
  523.         (void) sprintf(file, "%s/%s", home, MAILRC);
  524.     }
  525.  
  526.     cnt = 1;
  527.     tmp = getpath(file, &cnt);
  528.     if (cnt) {
  529.     if (cnt == -1) {
  530.         print("%s: %s\n", file, tmp);
  531.         return -1;
  532.     } else {
  533.         print("%s is a directory.\n", tmp);
  534.         return -2;
  535.     }
  536.     }
  537.     /* See if the file exists and confirm overwrite */
  538.     if (!Access(tmp, F_OK)) {
  539.     int overwrite = TRUE;
  540.     char buf[BUFSIZ];
  541.     if (!istool) {
  542.         print("\"%s\" exists. Overwrite? ", trim_filename(tmp));
  543.         if (Getstr(buf, 3, 0) <= 0 || lower(*buf) != 'y')
  544.         overwrite = FALSE;
  545.     }
  546. #ifdef SUNTOOL
  547.     else {
  548.         sprintf(buf, "\"%s\" exists. Overwrite? ", trim_filename(tmp));
  549.         overwrite = ask(buf);
  550.     }
  551. #endif /* SUNTOOL */
  552.     if (!overwrite) {
  553.         print("\"%s\" unchanged.\n", tmp);
  554.         return -3;
  555.     }
  556.     }
  557.     if (!(fp = fopen(tmp, "w"))) {
  558.     error("Can't open %s", file);
  559.     return -1;
  560.     }
  561.  
  562.     save_list("basic variable settings", set_options, "set", '=', fp);
  563.  
  564.     save_list("mail headers for outgoing mail", own_hdrs, "my_hdr", 0, fp);
  565.  
  566.     save_list("aliases", aliases, "alias", 0, fp);
  567.  
  568.     (void) alts(0, (char **)fp);
  569.  
  570.     save_list("headers to ignore", ignore_hdr, "ignore", ' ', fp);
  571.  
  572.     save_list("command abbreviations", functions, "cmd", ' ', fp);
  573.  
  574.     save_list("command macros for function keys", fkeys, "fkey", ' ', fp);
  575.  
  576. #ifdef CURSES
  577.     save_cmd("curses mode key bindings", cmd_map, "bind", 1, fp);
  578. #endif /* CURSES */
  579.  
  580.     save_cmd("line mode mappings", line_map, "map", 0, fp);
  581.  
  582.     save_cmd("composition mode mappings", bang_map, "map!", 0, fp);
  583.  
  584.     (void) fclose(fp);
  585.     print("All variables and options saved in %s\n", trim_filename(tmp));
  586.     return 0;
  587. }
  588.  
  589. save_list(title, list, command, equals, fp)
  590. struct options *list;
  591. register char *command, *title, equals;
  592. register FILE *fp;
  593. {
  594.     register struct options *opts;
  595.     register char *p;
  596.  
  597.     if (!list)
  598.     return;
  599.     (void) fprintf(fp, "#\n# %s\n#\n", title);
  600.     for (opts = list; opts; opts = opts->next) {
  601.     if (list == set_options && !strcmp(opts->option, "cwd"))
  602.         continue; /* don't print $cwd */
  603.     (void) fprintf(fp, "%s %s", command, opts->option);
  604.     if (opts->value && *opts->value) {
  605.         register char *quote;
  606.         if (!equals)
  607.         quote = NO_STRING;
  608.         else if (p = any(opts->value, "\"'"))
  609.         if (*p == '\'')
  610.             quote = "\"";
  611.         else
  612.             quote = "'";
  613.         else
  614.         if (!any(opts->value, " \t;|"))
  615.             quote = NO_STRING;
  616.         else
  617.             quote = "'";
  618.         (void) fputc(equals? equals: ' ', fp);
  619.         (void) fprintf(fp, "%s%s%s", quote, opts->value, quote);
  620.     }
  621.     (void) fputc('\n', fp);
  622.     }
  623. }
  624.  
  625. extern struct cmd_map map_func_names[];
  626.  
  627. save_cmd(title, list, command, equals, fp)
  628. struct cmd_map *list;
  629. register char *command, *title;
  630. register int equals;
  631. register FILE *fp;
  632. {
  633.     register struct cmd_map *opts;
  634.     register char *p;
  635.     char buf[MAX_MACRO_LEN * 2];
  636.  
  637.     if (!list)
  638.     return;
  639.     (void) fprintf(fp, "#\n# %s\n#\n", title);
  640.     for (opts = list; opts; opts = opts->m_next) {
  641.     register char *quote;
  642.     if ((p = any(opts->m_str, "\"'")) && *p == '\'')
  643.         quote = "\"";
  644.     else
  645.         quote = "'";
  646.     (void) fprintf(fp, "%s %s%s%s", command, quote,
  647.             ctrl_strcpy(buf, opts->m_str, TRUE), quote);
  648.     if (equals && map_func_names[opts->m_cmd].m_str)
  649.         (void) fprintf(fp, " %s", map_func_names[opts->m_cmd].m_str);
  650.     if (opts->x_str && *opts->x_str) {
  651.         if ((p = any(opts->x_str, "\"'")) && *p == '\'')
  652.         quote = "\"";
  653.         else
  654.         quote = "'";
  655.         (void) fprintf(fp, " %s%s%s", quote,
  656.             ctrl_strcpy(buf, opts->x_str, TRUE), quote);
  657.     }
  658.     (void) fputc('\n', fp);
  659.     }
  660. }
  661.  
  662. /*
  663.  * do_alias handles aliases, header settings, functions, and fkeys.
  664.  * since they're all handled in the same manner, the same routine is
  665.  * used. argv[0] determines which to use.
  666.  * alias is given here as an example
  667.  *
  668.  * alias           identify all aliases
  669.  * alias name      identify alias
  670.  * alias name arg1 arg2 arg3... -> name="arg1 arg2 arg3"; call add_option
  671.  * unalias arg1 [arg2 arg3 ... ]        unalias args
  672.  *
  673.  * same is true for dealing with your own headers.
  674.  * (also the expand command)
  675.  */
  676. do_alias(argc, argv)
  677. register char **argv;
  678. {
  679.     register char *cmd = *argv, *p;
  680.     struct options **list;
  681.     char firstchar = *cmd, buf[BUFSIZ];
  682.  
  683.     if (argc == 0)
  684.     return 0 - in_pipe();
  685.     if (firstchar == 'u')
  686.     firstchar = cmd[2];
  687.     if (*++argv && !strcmp(*argv, "-?")) { /* doesn't apply for fkeys */
  688.     register char *help_str;
  689.     if (firstchar == 'a' || firstchar == 'e')
  690.         help_str = "alias";
  691.     else if (firstchar == 'c')
  692.         help_str = "cmd";
  693.     else if (firstchar == 'f')
  694.         help_str = "fkey";
  695.     else
  696.         help_str = "my_hdr";
  697.     return help(0, help_str, cmd_help);
  698.     }
  699.  
  700.     if (firstchar == 'a')
  701.     list = &aliases;
  702.     else if (firstchar == 'c')
  703.     list = &functions;
  704.     else if (firstchar == 'f')
  705.     list = &fkeys;
  706.     else
  707.     list = &own_hdrs;
  708.  
  709.     if (*cmd == 'u') {
  710.     if (!*argv) {
  711.         print("%s what?\n", cmd);
  712.         return -1;
  713.     /* unset a list separated by spaces or ',' */
  714.     } else while (*argv) {
  715.         if (!strcmp(*argv, "*")) /* unset everything */
  716.         while (*list)
  717.             (void) un_set(list, (*list)->option);
  718.         else if (!un_set(list, *argv))
  719.         print("\"%s\" isn't set\n", *argv);
  720.         argv++;
  721.     }
  722. #ifdef SUNTOOL
  723.     if (istool > 1)
  724.         update_list_textsw(list);
  725. #endif /* SUNTOOL */
  726.     return 0;
  727.     }
  728.  
  729.     if (!*argv && *cmd != 'e') {
  730.     /* just type out all the aliases or own_hdrs */
  731.     (void) do_set(*list, NULL);
  732.     return 0;
  733.     }
  734.  
  735.     if (*cmd == 'e') {   /* command was "expand" (aliases only) */
  736.     if (!*argv) {
  737.         print("expand which alias?\n");
  738.         return -1;
  739.     } else
  740.         do  {
  741.         print("%s: ", *argv);
  742.         if (p = alias_to_address(*argv))
  743.             print("%s\n", p);
  744.         } while (*++argv);
  745.     return 0;
  746.     }
  747.  
  748.     /* at this point, *argv now points to a variable name ...
  749.      * check for hdr -- if so, *argv better end with a ':' (check *p)
  750.      */
  751.     if (list == &own_hdrs && !(p = index(*argv, ':'))) {
  752.     print("header labels must end with a ':' (%s)\n", *argv);
  753.     return -1;
  754.     }
  755.     if (!argv[1] && !index(*argv, '='))
  756.     if (p = do_set(*list, *argv))
  757.         print("%s\n", p);
  758.     else
  759.         print("%s is not set\n", *argv);
  760.     else {
  761.     char *tmpargv[2];
  762.     (void) argv_to_string(buf, argv);
  763.     if ((p = any(buf, " \t=")) && *p != '=')
  764.         *p = '=';
  765.     /* if we're setting an alias, enforce the insertion of commas
  766.      * between each well-formed address.
  767.      */
  768.     if (list == &aliases)
  769.         fix_up_addr(p+1);
  770.     tmpargv[0] = buf;
  771.     tmpargv[1] = NULL;
  772.     (void) add_option(list, tmpargv);
  773. #ifdef SUNTOOL
  774.     if (istool > 1)
  775.         update_list_textsw(list);
  776. #endif /* SUNTOOL */
  777.     }
  778.     return 0;
  779. }
  780.